home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-09  |  5.5 KB  |  206 lines

  1.  
  2. /* (C) Copyright by Dirk Heckmann and Aaron Digulla in D-7750 Konstanz
  3.  
  4.      $Id: debug.c 1.1 1994/09/09 12:31:30 digulla Exp digulla $
  5.  
  6.       This module provides everything to write save and clean
  7.       programs that allocate memory. This routine handles all
  8.       that's needed for allocating and freeing memory and de-
  9.       bugging the programm itself.
  10.  
  11.       Take care to include "debug_mem.h" in your module, where
  12.       you allocate memory and re-compile it !
  13.  
  14.       I use here code from the allround.lib by Dirk Heckmann.
  15.       Thanks for work, Dirk.
  16.  
  17.      date      done            by
  18.      10.08.90  initial release        D. Heckmann
  19.      01.08.91  modified for debug    A. Digulla
  20.      $Log: debug.c $
  21.  * Revision 1.1  1994/09/09  12:31:30  digulla
  22.  * Initial revision
  23.  *
  24.  
  25.      TODO
  26.       The method of replacing Message() by printf() has to be replaced.
  27.       We need a Requester or Alert here (especially for WB-Startup).
  28.  
  29. */
  30.  
  31.      /* Some defs and things we need in this module */
  32.  
  33. #include <exec/types.h>
  34. #include <exec/execbase.h>
  35. #include <exec/memory.h>
  36. #include <clib/exec_protos.h>
  37. #include <clib/dos_protos.h>
  38. #include <string.h>
  39.  
  40. #define DEBUG_C
  41. #include "debug_mem.h"
  42.  
  43. extern struct ExecBase * SysBase;
  44. #define ALLOCERROR     (1L << 31)
  45. #include <stdio.h>
  46.  
  47.  
  48. char message[256];     /* Place for the Output */
  49.  
  50.      /* _debug_AllocMem ()
  51.  
  52.      PARAMETER
  53.       long           size             ; like AllocMem ()
  54.       long           requirements         ; like AllocMem ()
  55.       const char * infotext          ; NEW !
  56.  
  57.      RETURN
  58.       void *
  59.  
  60.      DESCRIPTION
  61.  
  62.       This Function provides what every Amiga-Programmer always
  63.       wanted: a SAVE way of allocating memory. _debug_AllocMem
  64.       will write the size and position and name of the memory-
  65.       block in the TaskMem-list (which is tracked by Exec). So
  66.       we can check the block in _debug_FreeMem (no more gurus
  67.       8100000[59] !) and look whether there is memory left at
  68.       exitus.
  69.  
  70.       BEWARE: The infotext is NOT copied. YOU MUST NOT MODIFY
  71.       IT. It is defined in debug_mem.h.
  72.  
  73.       Because of the wonderful ability of DICE to create __auto-
  74.       exit-functions, we can then check for all non-freed mem-
  75.       ory ! */
  76.  
  77. void * _debug_AllocMem (long size, long reqs, const char * infotext)
  78.  
  79. {
  80.      struct MemList * ml;        /* Received from Exec via AllocEntry */
  81.      struct MemList   block;        /* That's what we want from Exec */
  82.      struct List    * tmem_list;    /* Pointer to the TaskMem-list */
  83.  
  84.       /* Initialize tmem_list */
  85.  
  86.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  87.  
  88.       /* Fill in the block with the requirements */
  89.  
  90.      block.ml_NumEntries       = 1;      /* just one entry */
  91.      block.ml_ME[0].me_Reqs       = reqs;   /* the requirements (MEMF_xxxx) */
  92.      block.ml_ME[0].me_Length       = size;   /* the size we want */
  93.  
  94.      ml = AllocEntry (&block);          /* get it */
  95.  
  96.      if ((ULONG)ml & ALLOCERROR)        /* Success ? */
  97.       return (NULL);                     /* sad */
  98.  
  99.       /* Add block to TaskMem-list */
  100.      AddTail (tmem_list, &ml->ml_Node);
  101.  
  102.       /* Add the infotext, so _debug_FreeAllMem() can find it */
  103.      ml->ml_Node.ln_Name = infotext;
  104.  
  105.      return (ml->ml_ME[0].me_Addr);   /* Give back address */
  106. } /* _debug_AllocMem () */
  107.  
  108.  
  109.      /* _debug_FreeMem ()
  110.  
  111.      PARAMETER
  112.       void         * memorypointer
  113.       long           blocksize
  114.       const char * infotext
  115.  
  116.      RETURN
  117.       - none -
  118.  
  119.      DESCRIPTION
  120.  
  121.       This is the opposite to _debug_AllocMem(). Here we give the
  122.       memory back to the system ... AFTER SOME CHECKS. So we will
  123.       never get any gurus for this !
  124.  
  125.       If _debug_FreeMem fails, we will get a message with more
  126.       information, why. */
  127.  
  128. void _debug_FreeMem (void * memptr, long size, const char * infotext)
  129.  
  130. {
  131.      struct MemList * ml;        /* This is what we found */
  132.      struct List    * tmem_list;    /* and here we look for it */
  133.  
  134.       /* Initialize tmem_list */
  135.  
  136.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  137.  
  138.       /* Get first entry out of the TaskMem-list */
  139.  
  140.      ml = (struct MemList *)tmem_list->lh_Head;
  141.  
  142.      while (ml->ml_Node.ln_Succ)
  143.      {
  144.       if (ml->ml_ME[0].me_Addr == memptr)
  145.       { /* found it ? */
  146.            struct MemEntry * me = ml->ml_ME;
  147.  
  148.            if (me->me_Length != size)
  149.            {
  150.             sprintf (message, "FreeMem(): Warning: Size mismatch error (old %d new %d)\n\t%s\n",
  151.              me->me_Length, size, infotext);
  152.             Write (Output(), message, strlen(message));
  153.             Delay (50);
  154.            }
  155.  
  156.            Remove (&ml->ml_Node);
  157.            FreeEntry (ml);
  158.            return ;
  159.       }
  160.  
  161.       ml = (struct MemList *)ml->ml_Node.ln_Succ;
  162.      } /* while ((struct Node *)ml->ln_Succ) */
  163.  
  164.      sprintf (message, "FreeMem(): Error: Memory not found (Addr $%08x Size %d)\n\t%s\n",
  165.       memptr, size, infotext);
  166.      Write (Output(), message, strlen(message));
  167.     Delay (50);
  168. } /* _debug_FreeMem () */
  169.  
  170.  
  171. void _debug_FreeAllMem (void)
  172.  
  173. {
  174.      struct MemList * ml;        /* This is what we found */
  175.      struct List    * tmem_list;    /* and here we look for it */
  176.  
  177.       /* Initialize tmem_list */
  178.  
  179.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  180.  
  181.       /* Get first entry out of the TaskMem-list */
  182.  
  183.      ml = (struct MemList *)tmem_list->lh_Head;
  184.  
  185.      while (ml->ml_Node.ln_Succ)
  186.      {
  187.       if (strncmp (ml->ml_Node.ln_Name, "AllocMem()", 10) == 0)
  188.       {
  189.              /* found an entry */
  190.            struct MemEntry * me = ml->ml_ME;
  191.  
  192.            sprintf (message, "FreeAllMem(): Error: Forgotten Memory (Addr $%08x Size %d)\n\t%s\n",
  193.             me->me_Addr, me->me_Length, ml->ml_Node.ln_Name);
  194.            Write (Output(), message, strlen(message));
  195.            Delay (50);
  196.  
  197.            Remove (&ml->ml_Node);
  198.            FreeEntry (ml);
  199.       }
  200.  
  201.       ml = (struct MemList *)ml->ml_Node.ln_Succ;
  202.      } /* while ((struct Node *)ml->ln_Succ) */
  203. } /* FreeAllMem () */
  204.  
  205.  
  206.